import { _decorator, Component, input, Node, Input, Animation, EventTouch, Vec3, Prefab, instantiate, Collider2D, Contact2DType, IPhysics2DContact, Sprite, AudioClip } from 'cc';
import { Reward, RewardType } from './Reward';
import { GameManager } from './GameManager';
import { LifeUI } from './UI/LifeUI';
import { AudioMgr } from './AudioMgr';
const { ccclass, property } = _decorator;

enum ShootType {
    OneShoot,
    TwoShoot
}
@ccclass('Player')
export class Player extends Component {
    @property
    shootRate: number = 0.5;
    @property(Node)
    position1: Node = null;
    @property(Node)
    position2: Node = null;
    @property(Node)
    position3: Node = null;
    @property(Animation)
    anim: Animation = null;
    @property(Node)
    bulletParent: Node = null;
    @property(Prefab)
    bullet1Prefab: Prefab = null;
    @property(Collider2D)
    collider: Collider2D = null;
    @property(Prefab)
    bullet2Prefab: Prefab = null;
    @property
    hp: number = 3;
    @property
    animHit: string = '';
    @property
    animDown: string = '';
    @property
    twoShootTime: number = 5;
    @property(LifeUI)
    lifeUI: LifeUI = null;
    @property
    invincibleTime: number = 1;
    invincibleTimer: number = 0;
    isInvicible: boolean = false;
    shootTimer: number = 0;
    twoShootTimer: number = 0;
    shootType: ShootType = ShootType.OneShoot;
    canControl: boolean = true;
    @property(AudioClip)
    bulletAudio: AudioClip = null;

    @property(AudioClip)
    getBombAudio: AudioClip = null;
    @property(AudioClip)
    getDoubleAudio: AudioClip = null;
    
    start() {
        this.lifeUI.updateUI(this.hp);
    }
    protected onLoad(): void {
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        if(this.collider){
            this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
    }
    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        const reward = otherCollider.getComponent(Reward);
        if(reward){
            this.onRewardContact(reward);
        }else{
            this.onEnemyContact();
        }
    }

    switchToTwoShoot() {
        this.twoShootTimer = 0;
        this.shootType = ShootType.TwoShoot;
    }

    switchToOneShoot() {
        this.shootType = ShootType.OneShoot;
    }
    lastReward: Reward = null;
    onRewardContact(reward: Reward) {
        if(reward == this.lastReward){
            return;
        }
        this.lastReward = reward;
        switch(reward.rewardType) {
            case RewardType.TowShoot:
                AudioMgr.inst.playOneShot(this.getDoubleAudio);
                this.switchToTwoShoot();
                break;
            case RewardType.Bomb:
                AudioMgr.inst.playOneShot(this.getBombAudio);
                GameManager.getInstance().addBomb();
                break;
        }
        reward.getComponent(Collider2D).enabled = false;
        reward.getComponent(Sprite).enabled = false;
    }

    onEnemyContact() {
        if(this.isInvicible) return;
        this.isInvicible = true;
        this.invincibleTimer = 0
        this.hp -= 1;
        this.lifeUI.updateUI(this.hp);
        if(this.hp <= 0){
            this.anim.play(this.animDown);
        }else{
            this.anim.play(this.animHit);
        }
        if(this.hp <= 0){
            if(this.collider){
                this.collider.enabled = false;
            }
            this.scheduleOnce(() => {
                GameManager.getInstance().gameOver();
            }, 0.4)
        }
    }

    protected onDestroy(): void {
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        if(this.collider){
            this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
    }
    onTouchMove(event: EventTouch) {
        if(!this.canControl) return;
        if(this.hp <=0) return;
        const position = new Vec3(this.node.position.x + event.getDeltaX(), this.node.position.y + event.getDeltaY(), this.node.position.z);
        if(position.x > 230){
            position.x = 230;
        }
        if(position.x < -230){
            position.x = -230;
        }
        if(position.y > 380){
            position.y = 380;
        }
        if(position.y < -380){
            position.y = -380
        }
        this.node.setPosition(position);
    }

    protected update(dt: number): void {
        if(this.isInvicible){
            this.invincibleTimer += dt;
            if(this.invincibleTimer >= this.invincibleTime){
                this.isInvicible = false
            }
        }
        if(this.hp > 0){
            switch(this.shootType){
                case ShootType.OneShoot:
                    this.oneShoot(dt);
                    break;
                case ShootType.TwoShoot:
                    this.twoShoot(dt);
                    break;
            }
        }
    }

    oneShoot(dt: number){
        this.shootTimer += dt;
        if(this.shootTimer >= this.shootRate){
            AudioMgr.inst.playOneShot(this.bulletAudio, 0.1)
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet1Prefab);
            this.bulletParent.addChild(bullet1);
            bullet1.setWorldPosition(this.position1.worldPosition);
        }
    }

    twoShoot(dt: number){
        this.twoShootTimer += dt;
        if(this.twoShootTimer > this.twoShootTime){
            this.switchToOneShoot();
        }
        this.shootTimer += dt;
        if(this.shootTimer >= this.shootRate){
            AudioMgr.inst.playOneShot(this.bulletAudio, 0.1)
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet2Prefab);
            const bullet2 = instantiate(this.bullet2Prefab);
            this.bulletParent.addChild(bullet1);
            this.bulletParent.addChild(bullet2);
            bullet1.setWorldPosition(this.position2.worldPosition);
            bullet2.setWorldPosition(this.position3.worldPosition);
        }
    }

    disableControl() {
        this.canControl = false;
    }

    enableControl() {
        this.canControl = true;
    }
}


